<template>
  <Drag
    :scrollX="scrollX"
    :scrollY="scrollY"
    :isSvg="true"
    :hasCancelHandle="true"
    :scale="scale"
    :x="item.x"
    :y="item.y"
    :bounds="bounds"
    :isStill="isStill"
    :fullScreen="fullScreen"
    @startMove="startMove"
    @move="onMove"
    @click="nodeChoose"
    @dragEnd="nodeDragEnd"
  >
    <g
      class="pane-cell pane-node selected"
      @click.stop="nodeChoose"
      @contextmenu.prevent="contextNode($event, item)"
    >
      <g class="pane-scalable">
        <foreignObject width="180" height="50">
          <body xmlns="http://www.w3.org/1999/xhtml">
            <div
              class="pane-node-content element-model has-status"
              :class="{'active': activeNode === item.id}"
            >
              <i :class="['iconfont',item.nodeIcon ? item.nodeIcon:'icon-datas']"></i>

              <span class="name" :title="item.name">{{item.name}}</span>

              <!-- 状态 -->
              <span class="status-icon" v-if="item.status">
                <i class="iconfont icon-success" v-if="item.status === 'SUCCESS'" title="执行成功"></i>
                <i class="iconfont icon-error" v-if="item.status === 'FAIL'" title="执行失败"></i>
                <i class="icon-loading-gif" v-if="item.status === 'RUNNING'" title="执行中"></i>
              </span>

              <!-- 数据流组件 -->
              <template v-if="dataFlow">
                <!-- 节点进 -->
                <div
                  class="pane-port-list in dataflow-in"
                  v-for="(unit,index) of inputPorts"
                  :key="new Date().getTime() * Math.random() * (index+1)"
                  :data-type="unit.type"
                  :title="unit.description"
                >
                  <div
                    class="pane-port-wrap"
                    :style="{width: (100 / (inputPorts.length + 1)) * (index + 1) + '%'}"
                  >
                    <div
                      class="pane-port"
                      :class="{'is-connectable': (isNewLink && flowNode && unit.type === flowNode.type && item.id!==currentNode.id) ||
                      (isNewLink && compatibleToDataFlow && item.id!==currentNode.id)}"
                    >
                      <span class="port-magnet cancel"></span>
                    </div>
                  </div>
                </div>

                <!-- 节点出 -->
                <div
                  class="pane-port-list out dataflow-out"
                  v-for="(unit,index) of outputPorts"
                  :key="new Date().getTime() * Math.random() * (index+1)"
                  :title="unit.description"
                  :data-type="unit.type"
                >
                  <div
                    class="pane-port-wrap"
                    :style="{width: (100 / (outputPorts.length + 1)) * (index + 1) + '%'}"
                  >
                    <div
                      class="pane-port"
                      @mousedown="onStart($event,unit,true)"
                      @mouseup="onEnd($event,unit,true)"
                    >
                      <span class="port-magnet cancel"></span>
                    </div>
                  </div>
                </div>
              </template>

              <!-- 普通组件 -->
              <template v-if="!dataFlow">
                <!-- 节点进 -->
                <div
                  v-if="item.categoryId!==wfCode.IMPORT && item.pipelineTaskNodeType!==wfCode.IMPORT"
                  class="pane-port-list in"
                >
                  <div class="pane-port-wrap" :style="{width: '50%'}">
                    <div
                      class="pane-port"
                      :class="{'is-connectable': flowNode ? (isNewLink && item.systemNode && item.systemNode.compatibleToDataFlow && item.id!==currentNode.id) :(isNewLink && item.id!==currentNode.id)}"
                    >
                      <span class="port-magnet cancel"></span>
                    </div>
                  </div>
                </div>

                <!-- 节点出 -->
                <div
                  v-if="item.categoryId!==wfCode.EXPORT && item.pipelineTaskNodeType!==wfCode.EXPORT"
                  class="pane-port-list out"
                >
                  <div class="pane-port-wrap" :style="{width: '50%'}">
                    <div class="pane-port" @mousedown="onStart" @mouseup="onEnd">
                      <span class="port-magnet cancel"></span>
                    </div>
                  </div>
                </div>
              </template>
            </div>
          </body>
        </foreignObject>
      </g>
    </g>
  </Drag>
</template>

<script>
import { mapState, mapMutations } from 'vuex';
import { wfCode } from 'assets/scripts/code';
import Drag from './Drag';
const doc = document;
export default {
  components: {
    Drag: Drag
  },
  computed: {
    ...mapState({
      currentNode: state => state.workflow.currentNode
    })
  },
  data: function () {
    return {
      x: null,
      y: null,
      // currentNode: null,
      wfCode: wfCode,
      dataFlow: false,
      inputPorts: [],
      outputPorts: [],
      flowNodeCurrent: null,
      compatibleCurrent: false // 是否可以连接数据流组件
    };
  },
  props: {
    item: {
      type: Object,
      default: function () {
        return {};
      }
    },
    isNewLink: {
      type: Boolean,
      default: false
    },
    isStill: {
      type: Boolean,
      default: false
    },
    isHasLink: {
      type: Boolean,
      default: true
    },
    fullScreen: {
      type: Boolean,
      default: false
    },
    bounds: {
      type: Object,
      default: function () {
        return {};
      }
    },
    scrollX: {
      type: Number,
      default: 0
    },
    scrollY: {
      type: Number,
      default: 0
    },
    spaceX: {
      type: Number,
      default: 0
    },
    spaceY: {
      type: Number,
      default: 0
    },
    activeNode: {
      type: String,
      default: '-'
    },
    scale: {
      type: Number,
      default: 1
    },
    flowNode: {
      type: Object,
      default: null
    },
    compatibleToDataFlow: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    ...mapMutations(['setCurrentNode']),

    // 节点开始拖拽
    startMove () {
      this.$emit('startNodeChange', this.item.name);
    },

    // 节点拖拽
    onMove (data) {
      this.$emit('paneNodeChange', { id: this.item.id, ...data });
    },

    // 节点选择
    nodeChoose () {
      this.$emit('nodeChoose', this.item);
    },

    // 节点拖拽结束
    nodeDragEnd () {
      this.$emit('nodeDragEnd', this.item);
    },

    // 找链接点
    move (event) {
      // event.pageX - this.spaceX - 240 点击的点相对于框的距离
      // event.pageY - this.spaceY + this.scrollY 点击的点相对于顶部的距离
      this.x = (event.pageX - this.spaceX - 240 + this.scrollX) / this.scale;
      this.y = (event.pageY - this.spaceY + this.scrollY) / this.scale;
      this.$emit('linkChange', {
        id: this.item.id,
        x: this.x,
        y: this.y,
        flowNode: this.flowNodeCurrent
      });
      this.$emit('isConnect', {
        bool: true,
        flowNode: this.flowNodeCurrent,
        compatibleToDataFlow: this.compatibleCurrent
      });
    },

    /**
     * 点击出去的点的时候
     * @item 点击的点信息
     * @boolean 是否是数据流组件
     */
    onStart (e, item, boolean) {
      // 当前操作的流数据信息
      this.flowNodeCurrent = boolean ? item : null;

      doc.body.style.userSelect = 'none';
      doc.addEventListener('mousemove', this.move);
      doc.addEventListener('mouseup', this.onEnd);

      this.setCurrentNode(this.item);
      this.$emit('nodeChoose', this.item);
    },

    // 放下点的点击
    onEnd (event) {
      event.preventDefault();

      doc.body.style.userSelect = '';
      doc.removeEventListener('mousemove', this.move);
      doc.removeEventListener('mouseup', this.onEnd);

      this.$emit('isConnect', {
        id: this.item.id, // 出来的id
        bool: false, // 标识放下了
        x: this.x,
        y: this.y,
        flowNode: this.flowNodeCurrent,
        compatibleToDataFlow: this.compatibleCurrent
      });
    },

    // 右键行为
    contextNode (e, item) {
      this.$emit('coverShow', { e, item });
    }
  },
  mounted () {
    if (this.item.systemNode) {
      let systemNode = this.item.systemNode;
      this.dataFlow = systemNode.dataFlow ? systemNode.dataFlow : false;
      this.inputPorts = systemNode.inputPorts ? systemNode.inputPorts : [];
      this.outputPorts = systemNode.outputPorts ? systemNode.outputPorts : [];
      this.compatibleCurrent = systemNode.compatibleToDataFlow ? systemNode.compatibleToDataFlow : false;
    }
  }
};
</script>

<style scoped lang="less" rel="stylesheet/less">
.pane-node body {
  min-width: 180px;
  padding-top: 5px;
}

.pane-group body,
.pane-group foreignObject,
.pane-node body,
.pane-node foreignObject {
  background-color: transparent;
  overflow: visible;
}

.pane-group,
.pane-node {
  user-drag: none;
  cursor: hand;
  cursor: -webkit-grab;
}

.pane-node-content {
  width: 180px;
  height: 40px;
  background-color: hsla(0, 0%, 100%, 0.9);
  border: 1px solid #007bff;
  border-radius: 5px;
  font-size: 12px;
  transition: background-color 0.2s;
  box-sizing: border-box;

  &:hover {
    background-color: rgba(227, 244, 255, 0.9);
  }

  &.active {
    background-color: #bdf5bd;
  }

  .iconfont {
    font-size: 18px;
    color: #007bff;
    width: 37px;
    height: 36px;
    float: left;
    margin: 1px;
    text-align: center;
    line-height: 36px;
  }

  .status {
    display: none;
    float: right;
    font-size: 18px;

    &.icon-warning-o {
      color: #f15e5e;
    }

    &:before {
      float: left;
    }
  }

  .name {
    width: 103px;
    height: 26px;
    overflow: hidden;
    float: left;
    font-size: 12px;
    line-height: 38px;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .status-icon {
    border-left: 1px solid #dcdfe6;
    text-align: center;
    float: left;
    width: 36px;
    height: 36px;

    .icon-success {
      color: #19be6b;
    }

    .icon-error {
      color: #ed4014;
    }

    .icon-loading-gif {
      background: url("~assets/images/loading.gif");
      width: 36px;
      height: 36px;
      display: inline-block;
      background-repeat: no-repeat;
      background-position: center;
    }
  }

  .pane-port {
    border: 1px solid #007bff;
    border-radius: 50%;
    background-color: #fff;
    -webkit-transition: background-color 0.2s;
    transition: background-color 0.2s;
    box-sizing: border-box;

    .port-magnet {
      width: 25px;
      height: 20px;
      margin: -6px 0 0 -6px;
      float: left;
      background-color: transparent;
      border-radius: 50%;
      background-color: transparent;
      border-radius: 50%;
    }

    &.is-connectable {
      .port-magnet {
        width: 40px;
        height: 40px;
        margin: -16px 0 0 -16px;
        float: left;
        background-color: transparent;
        border-radius: 50%;

        &:before {
          width: 20px;
          height: 20px;
          margin: 10px 0 0 10px;
          float: left;
          box-sizing: content-box;
          border-radius: 50%;
          background-color: rgba(57, 202, 116, 0.6);
          content: " ";
        }

        &:after {
          width: 10px;
          height: 10px;
          margin: -15px 0 0 15px;
          float: left;
          clear: both;
          box-sizing: border-box;
          border: 1px solid #39ca74;
          border-radius: 50%;
          background-color: #fff;
          content: " ";
        }

        &.is-adsorbed:after {
          margin-top: -19px;
        }

        &.is-adsorbed:before {
          width: 28px;
          height: 28px;
          margin: 6px 0 0 6px;
        }
      }
    }
  }

  .pane-port-wrap {
    float: left;
    height: 1px;
  }

  &.has-status {
    .status {
      display: block;
    }
  }

  &.before {
    border-color: #808080;

    .icon {
      background: #808080;
    }

    .name {
      color: #808080;
    }
  }

  &.wrong {
    border-color: #db4437;

    .icon {
      background: #db4437;
    }

    .name {
      color: #db4437;
    }
  }

  &.down,
  &.running {
    border-color: #0f9d58;

    .icon {
      background: #0f9d58;
    }

    .name {
      color: #0f9d58;
    }
  }

  &.running {
    .name {
      text-overflow: unset;
      animation: text-run 3s linear infinite;
    }
  }
}

.pane-port-list {
  float: left;
  width: 180px;
  margin-top: -5px;

  &.in {
    clear: both;
    margin-top: -42px;

    .pane-port {
      cursor: default;
      width: 8px;
      height: 8px;
      margin: -1px -2px 0 0;
      float: right;
      border: 1px solid #007bff;
      border-radius: 50%;
      background-color: #fff;
      transition: background-color 0.2s;
      box-sizing: border-box;
      &.is-connected {
        // border-style: solid;
        // border-width: 5px 4px 0;
        // border-color: gray transparent transparent;
        // background-color: transparent;
        // border-radius: 0;
      }
    }
  }

  &.out {
    margin-top: -2px;
    clear: both;

    .pane-port {
      cursor: crosshair;
      width: 8px;
      height: 8px;
      margin: -1px -2px 0 0;
      float: right;
      border: 1px solid #007bff;
      border-radius: 50%;
      background-color: #fff;
      transition: background-color 0.2s;
      box-sizing: border-box;

      &:hover {
        background-color: gray;
      }
    }
  }
}

@keyframes text-run {
  0% {
    text-indent: -4px;
  }
  100% {
    text-indent: 100%;
  }
}

@keyframes circle-run2 {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
